package com.kitten.dataAlign.job.dataAlign;

import cn.hutool.core.collection.CollUtil;
import com.kitten.dataAlign.constants.RedisKeyConstants;
import com.kitten.dataAlign.constants.TableConstants;
import com.kitten.dataAlign.domain.mapper.DeleteMapper;
import com.kitten.dataAlign.domain.mapper.SelectMapper;
import com.kitten.dataAlign.domain.mapper.UpdateMapper;
import com.kitten.dataAlign.rpc.SearchRpcService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author kitten
 */
@Slf4j
@Component
public class FollowingCountShardingXxlJob {
    
    @Resource
    private SelectMapper selectMapper;
    @Autowired
    private UpdateMapper updateMapper;
    @Autowired
    @Resource
    private DeleteMapper deleteMapper;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private SearchRpcService searchRpcService;


    /**
     * 分片任务
     * @throws Exception
     */
    @XxlJob("followingCountShardingJobHandler")
    public void followingCountShardingJobHandler() throws Exception {
        // 分片序号
        int shardIndex = XxlJobHelper.getShardIndex();
        // 分片总数
        int shardTotal = XxlJobHelper.getShardTotal();

        XxlJobHelper.log("分片参数：当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
        log.info("分片参数：当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);

        // 1. 分批次查询 t_data_align_following_count_temp_日期_分片序号，如一批次查询 1000 条，直到全部查询完成
        String date = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String tableNameSuffix = TableConstants.buildTableNameSuffix(date, shardIndex);
        int batchSize = 1000; // 每批查询 1000 条
        int processedTotal = 0; // 已处理的记录数

        // 死循环
        for (;;) {
            // 1. 分批次查询，如一批次查询 1000 条，直到全部查询完成
            List<Long> userIds = selectMapper.selectBatchFromDataAlignFollowingCountTempTable(tableNameSuffix, batchSize);  // 查询今日有哪些user触发关注行为

            // 若记录为空，终止循环
            if (CollUtil.isEmpty(userIds)) break;

            // 循环这一批发生变更的用户 ID
            userIds.forEach(userId -> {
                // 2: 对 t_following 关注表执行 count(*) 操作，获取关注总数
                int followingTotal = selectMapper.selectCountFromFollowingTableByUserId(userId);

                // : 3: 更新 t_user_count 表, 更新对应 Redis 缓存
                int count = updateMapper.updateUserFollowingTotalByUserId(userId, followingTotal);
                if (count > 0) {
                    String key = RedisKeyConstants.buildCountUserKey(userId);   // count:user:userId
                    Boolean hasKey = redisTemplate.hasKey(key);
                    if (hasKey) {
                        redisTemplate.opsForHash().put(key, RedisKeyConstants.FIELD_FOLLOWING_TOTAL, followingTotal);
                    }
                }
            });

            // : 4. 批量物理删除这一批次记录
            deleteMapper.batchDeleteDataAlignFollowingCountTempTable(tableNameSuffix, userIds);
            // 当前已处理的记录数
            processedTotal += userIds.size();
        }
        XxlJobHelper.log("结束本次定时任务, 本次处理记录数：{}", processedTotal);

    }

}
